home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / arch / sparc / include / asm / spitfire.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  9.0 KB  |  343 lines

  1. /* spitfire.h: SpitFire/BlackBird/Cheetah inline MMU operations.
  2.  *
  3.  * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  4.  */
  5.  
  6. #ifndef _SPARC64_SPITFIRE_H
  7. #define _SPARC64_SPITFIRE_H
  8.  
  9. #include <asm/asi.h>
  10.  
  11. /* The following register addresses are accessible via ASI_DMMU
  12.  * and ASI_IMMU, that is there is a distinct and unique copy of
  13.  * each these registers for each TLB.
  14.  */
  15. #define TSB_TAG_TARGET        0x0000000000000000 /* All chips                */
  16. #define TLB_SFSR        0x0000000000000018 /* All chips                */
  17. #define TSB_REG            0x0000000000000028 /* All chips                */
  18. #define TLB_TAG_ACCESS        0x0000000000000030 /* All chips                */
  19. #define VIRT_WATCHPOINT        0x0000000000000038 /* All chips                */
  20. #define PHYS_WATCHPOINT        0x0000000000000040 /* All chips                */
  21. #define TSB_EXTENSION_P        0x0000000000000048 /* Ultra-III and later        */
  22. #define TSB_EXTENSION_S        0x0000000000000050 /* Ultra-III and later, D-TLB only    */
  23. #define TSB_EXTENSION_N        0x0000000000000058 /* Ultra-III and later        */
  24. #define TLB_TAG_ACCESS_EXT    0x0000000000000060 /* Ultra-III+ and later        */
  25.  
  26. /* These registers only exist as one entity, and are accessed
  27.  * via ASI_DMMU only.
  28.  */
  29. #define PRIMARY_CONTEXT        0x0000000000000008
  30. #define SECONDARY_CONTEXT    0x0000000000000010
  31. #define DMMU_SFAR        0x0000000000000020
  32. #define VIRT_WATCHPOINT        0x0000000000000038
  33. #define PHYS_WATCHPOINT        0x0000000000000040
  34.  
  35. #define SPITFIRE_HIGHEST_LOCKED_TLBENT    (64 - 1)
  36. #define CHEETAH_HIGHEST_LOCKED_TLBENT    (16 - 1)
  37.  
  38. #define L1DCACHE_SIZE        0x4000
  39.  
  40. #define SUN4V_CHIP_INVALID    0x00
  41. #define SUN4V_CHIP_NIAGARA1    0x01
  42. #define SUN4V_CHIP_NIAGARA2    0x02
  43. #define SUN4V_CHIP_UNKNOWN    0xff
  44.  
  45. #ifndef __ASSEMBLY__
  46.  
  47. enum ultra_tlb_layout {
  48.     spitfire = 0,
  49.     cheetah = 1,
  50.     cheetah_plus = 2,
  51.     hypervisor = 3,
  52. };
  53.  
  54. extern enum ultra_tlb_layout tlb_type;
  55.  
  56. extern int sun4v_chip_type;
  57.  
  58. extern int cheetah_pcache_forced_on;
  59. extern void cheetah_enable_pcache(void);
  60.  
  61. #define sparc64_highest_locked_tlbent()    \
  62.     (tlb_type == spitfire ? \
  63.      SPITFIRE_HIGHEST_LOCKED_TLBENT : \
  64.      CHEETAH_HIGHEST_LOCKED_TLBENT)
  65.  
  66. extern int num_kernel_image_mappings;
  67.  
  68. /* The data cache is write through, so this just invalidates the
  69.  * specified line.
  70.  */
  71. static inline void spitfire_put_dcache_tag(unsigned long addr, unsigned long tag)
  72. {
  73.     __asm__ __volatile__("stxa    %0, [%1] %2\n\t"
  74.                  "membar    #Sync"
  75.                  : /* No outputs */
  76.                  : "r" (tag), "r" (addr), "i" (ASI_DCACHE_TAG));
  77. }
  78.  
  79. /* The instruction cache lines are flushed with this, but note that
  80.  * this does not flush the pipeline.  It is possible for a line to
  81.  * get flushed but stale instructions to still be in the pipeline,
  82.  * a flush instruction (to any address) is sufficient to handle
  83.  * this issue after the line is invalidated.
  84.  */
  85. static inline void spitfire_put_icache_tag(unsigned long addr, unsigned long tag)
  86. {
  87.     __asm__ __volatile__("stxa    %0, [%1] %2\n\t"
  88.                  "membar    #Sync"
  89.                  : /* No outputs */
  90.                  : "r" (tag), "r" (addr), "i" (ASI_IC_TAG));
  91. }
  92.  
  93. static inline unsigned long spitfire_get_dtlb_data(int entry)
  94. {
  95.     unsigned long data;
  96.  
  97.     __asm__ __volatile__("ldxa    [%1] %2, %0"
  98.                  : "=r" (data)
  99.                  : "r" (entry << 3), "i" (ASI_DTLB_DATA_ACCESS));
  100.  
  101.     /* Clear TTE diag bits. */
  102.     data &= ~0x0003fe0000000000UL;
  103.  
  104.     return data;
  105. }
  106.  
  107. static inline unsigned long spitfire_get_dtlb_tag(int entry)
  108. {
  109.     unsigned long tag;
  110.  
  111.     __asm__ __volatile__("ldxa    [%1] %2, %0"
  112.                  : "=r" (tag)
  113.                  : "r" (entry << 3), "i" (ASI_DTLB_TAG_READ));
  114.     return tag;
  115. }
  116.  
  117. static inline void spitfire_put_dtlb_data(int entry, unsigned long data)
  118. {
  119.     __asm__ __volatile__("stxa    %0, [%1] %2\n\t"
  120.                  "membar    #Sync"
  121.                  : /* No outputs */
  122.                  : "r" (data), "r" (entry << 3),
  123.                    "i" (ASI_DTLB_DATA_ACCESS));
  124. }
  125.  
  126. static inline unsigned long spitfire_get_itlb_data(int entry)
  127. {
  128.     unsigned long data;
  129.  
  130.     __asm__ __volatile__("ldxa    [%1] %2, %0"
  131.                  : "=r" (data)
  132.                  : "r" (entry << 3), "i" (ASI_ITLB_DATA_ACCESS));
  133.  
  134.     /* Clear TTE diag bits. */
  135.     data &= ~0x0003fe0000000000UL;
  136.  
  137.     return data;
  138. }
  139.  
  140. static inline unsigned long spitfire_get_itlb_tag(int entry)
  141. {
  142.     unsigned long tag;
  143.  
  144.     __asm__ __volatile__("ldxa    [%1] %2, %0"
  145.                  : "=r" (tag)
  146.                  : "r" (entry << 3), "i" (ASI_ITLB_TAG_READ));
  147.     return tag;
  148. }
  149.  
  150. static inline void spitfire_put_itlb_data(int entry, unsigned long data)
  151. {
  152.     __asm__ __volatile__("stxa    %0, [%1] %2\n\t"
  153.                  "membar    #Sync"
  154.                  : /* No outputs */
  155.                  : "r" (data), "r" (entry << 3),
  156.                    "i" (ASI_ITLB_DATA_ACCESS));
  157. }
  158.  
  159. static inline void spitfire_flush_dtlb_nucleus_page(unsigned long page)
  160. {
  161.     __asm__ __volatile__("stxa    %%g0, [%0] %1\n\t"
  162.                  "membar    #Sync"
  163.                  : /* No outputs */
  164.                  : "r" (page | 0x20), "i" (ASI_DMMU_DEMAP));
  165. }
  166.  
  167. static inline void spitfire_flush_itlb_nucleus_page(unsigned long page)
  168. {
  169.     __asm__ __volatile__("stxa    %%g0, [%0] %1\n\t"
  170.                  "membar    #Sync"
  171.                  : /* No outputs */
  172.                  : "r" (page | 0x20), "i" (ASI_IMMU_DEMAP));
  173. }
  174.  
  175. /* Cheetah has "all non-locked" tlb flushes. */
  176. static inline void cheetah_flush_dtlb_all(void)
  177. {
  178.     __asm__ __volatile__("stxa    %%g0, [%0] %1\n\t"
  179.                  "membar    #Sync"
  180.                  : /* No outputs */
  181.                  : "r" (0x80), "i" (ASI_DMMU_DEMAP));
  182. }
  183.  
  184. static inline void cheetah_flush_itlb_all(void)
  185. {
  186.     __asm__ __volatile__("stxa    %%g0, [%0] %1\n\t"
  187.                  "membar    #Sync"
  188.                  : /* No outputs */
  189.                  : "r" (0x80), "i" (ASI_IMMU_DEMAP));
  190. }
  191.  
  192. /* Cheetah has a 4-tlb layout so direct access is a bit different.
  193.  * The first two TLBs are fully assosciative, hold 16 entries, and are
  194.  * used only for locked and >8K sized translations.  One exists for
  195.  * data accesses and one for instruction accesses.
  196.  *
  197.  * The third TLB is for data accesses to 8K non-locked translations, is
  198.  * 2 way assosciative, and holds 512 entries.  The fourth TLB is for
  199.  * instruction accesses to 8K non-locked translations, is 2 way
  200.  * assosciative, and holds 128 entries.
  201.  *
  202.  * Cheetah has some bug where bogus data can be returned from
  203.  * ASI_{D,I}TLB_DATA_ACCESS loads, doing the load twice fixes
  204.  * the problem for me. -DaveM
  205.  */
  206. static inline unsigned long cheetah_get_ldtlb_data(int entry)
  207. {
  208.     unsigned long data;
  209.  
  210.     __asm__ __volatile__("ldxa    [%1] %2, %%g0\n\t"
  211.                  "ldxa    [%1] %2, %0"
  212.                  : "=r" (data)
  213.                  : "r" ((0 << 16) | (entry << 3)),
  214.                  "i" (ASI_DTLB_DATA_ACCESS));
  215.  
  216.     return data;
  217. }
  218.  
  219. static inline unsigned long cheetah_get_litlb_data(int entry)
  220. {
  221.     unsigned long data;
  222.  
  223.     __asm__ __volatile__("ldxa    [%1] %2, %%g0\n\t"
  224.                  "ldxa    [%1] %2, %0"
  225.                  : "=r" (data)
  226.                  : "r" ((0 << 16) | (entry << 3)),
  227.                  "i" (ASI_ITLB_DATA_ACCESS));
  228.  
  229.     return data;
  230. }
  231.  
  232. static inline unsigned long cheetah_get_ldtlb_tag(int entry)
  233. {
  234.     unsigned long tag;
  235.  
  236.     __asm__ __volatile__("ldxa    [%1] %2, %0"
  237.                  : "=r" (tag)
  238.                  : "r" ((0 << 16) | (entry << 3)),
  239.                  "i" (ASI_DTLB_TAG_READ));
  240.  
  241.     return tag;
  242. }
  243.  
  244. static inline unsigned long cheetah_get_litlb_tag(int entry)
  245. {
  246.     unsigned long tag;
  247.  
  248.     __asm__ __volatile__("ldxa    [%1] %2, %0"
  249.                  : "=r" (tag)
  250.                  : "r" ((0 << 16) | (entry << 3)),
  251.                  "i" (ASI_ITLB_TAG_READ));
  252.  
  253.     return tag;
  254. }
  255.  
  256. static inline void cheetah_put_ldtlb_data(int entry, unsigned long data)
  257. {
  258.     __asm__ __volatile__("stxa    %0, [%1] %2\n\t"
  259.                  "membar    #Sync"
  260.                  : /* No outputs */
  261.                  : "r" (data),
  262.                    "r" ((0 << 16) | (entry << 3)),
  263.                    "i" (ASI_DTLB_DATA_ACCESS));
  264. }
  265.  
  266. static inline void cheetah_put_litlb_data(int entry, unsigned long data)
  267. {
  268.     __asm__ __volatile__("stxa    %0, [%1] %2\n\t"
  269.                  "membar    #Sync"
  270.                  : /* No outputs */
  271.                  : "r" (data),
  272.                    "r" ((0 << 16) | (entry << 3)),
  273.                    "i" (ASI_ITLB_DATA_ACCESS));
  274. }
  275.  
  276. static inline unsigned long cheetah_get_dtlb_data(int entry, int tlb)
  277. {
  278.     unsigned long data;
  279.  
  280.     __asm__ __volatile__("ldxa    [%1] %2, %%g0\n\t"
  281.                  "ldxa    [%1] %2, %0"
  282.                  : "=r" (data)
  283.                  : "r" ((tlb << 16) | (entry << 3)), "i" (ASI_DTLB_DATA_ACCESS));
  284.  
  285.     return data;
  286. }
  287.  
  288. static inline unsigned long cheetah_get_dtlb_tag(int entry, int tlb)
  289. {
  290.     unsigned long tag;
  291.  
  292.     __asm__ __volatile__("ldxa    [%1] %2, %0"
  293.                  : "=r" (tag)
  294.                  : "r" ((tlb << 16) | (entry << 3)), "i" (ASI_DTLB_TAG_READ));
  295.     return tag;
  296. }
  297.  
  298. static inline void cheetah_put_dtlb_data(int entry, unsigned long data, int tlb)
  299. {
  300.     __asm__ __volatile__("stxa    %0, [%1] %2\n\t"
  301.                  "membar    #Sync"
  302.                  : /* No outputs */
  303.                  : "r" (data),
  304.                    "r" ((tlb << 16) | (entry << 3)),
  305.                    "i" (ASI_DTLB_DATA_ACCESS));
  306. }
  307.  
  308. static inline unsigned long cheetah_get_itlb_data(int entry)
  309. {
  310.     unsigned long data;
  311.  
  312.     __asm__ __volatile__("ldxa    [%1] %2, %%g0\n\t"
  313.                  "ldxa    [%1] %2, %0"
  314.                  : "=r" (data)
  315.                  : "r" ((2 << 16) | (entry << 3)),
  316.                                "i" (ASI_ITLB_DATA_ACCESS));
  317.  
  318.     return data;
  319. }
  320.  
  321. static inline unsigned long cheetah_get_itlb_tag(int entry)
  322. {
  323.     unsigned long tag;
  324.  
  325.     __asm__ __volatile__("ldxa    [%1] %2, %0"
  326.                  : "=r" (tag)
  327.                  : "r" ((2 << 16) | (entry << 3)), "i" (ASI_ITLB_TAG_READ));
  328.     return tag;
  329. }
  330.  
  331. static inline void cheetah_put_itlb_data(int entry, unsigned long data)
  332. {
  333.     __asm__ __volatile__("stxa    %0, [%1] %2\n\t"
  334.                  "membar    #Sync"
  335.                  : /* No outputs */
  336.                  : "r" (data), "r" ((2 << 16) | (entry << 3)),
  337.                    "i" (ASI_ITLB_DATA_ACCESS));
  338. }
  339.  
  340. #endif /* !(__ASSEMBLY__) */
  341.  
  342. #endif /* !(_SPARC64_SPITFIRE_H) */
  343.